home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_01 / 9n01059a < prev    next >
Text File  |  1990-11-14  |  3KB  |  96 lines

  1.  
  2. /* ************************* */
  3. /* Multi-threading functions */
  4.  
  5. #include <setjmp.h>
  6. #define  TSTACKSIZE 200   /* Stack space reseved in each thread in words */
  7. #define  MAXTHREAD 20       /* Max No of concurrent threads */
  8. #define  SPINDX  1        /* Index of stack pointer into env */
  9. #define  NULL 0
  10. static struct threaddat {
  11.        int     *env ;        /* Environment pointer */
  12.        int     (*tfp)() ;    /* Thread function pointer */
  13.        int     state ;       /* 0 Waiting 1 running -1 terminated */
  14.                } threaddata[MAXTHREAD] ;
  15. /* Globals for thread() */
  16. static jmp_buf envroot ;          /* root environment */
  17. static int threadnum = -1 ;       /* Number of threads */
  18. static int threadindx ;              /* Thread indexer */
  19. /* Takes a NULL terminated list of function pointers, sets up
  20.    the global parameters above and the root environment and then
  21.    calls threadrun() to define and run the function threads. */
  22. thread(fplist)
  23. int (*fplist)() ;
  24. {
  25.   int  (**fplptr)() ;
  26.   void threadrun() ;
  27.   if (threadnum == -1)
  28.    { fplptr = &fplist ;
  29.      threadnum = 0 ;
  30.      while (*fplptr != NULL)
  31.         threaddata[threadnum++].tfp = *fplptr++ ;
  32.      threadindx = 0 ;
  33.      if (!setjmp(envroot))
  34.        threadrun() ;         /* define thread environments recursivly */
  35.                                    /* then run them to extinction */
  36.    }
  37. }
  38. /* recusivly defines thread environments then runs in round robin */
  39. void threadrun()
  40. {
  41.   jmp_buf envthread ;
  42.   int stackspace[TSTACKSIZE] ;
  43.   if (threadindx < threadnum)
  44.     { if (setjmp(envthread))
  45.        { /* Will arrive here by longjmp  for function dispatch */
  46.          (*threaddata[threadindx].tfp)() ;      /* Start thread */
  47.          threaddata[threadindx].state = -1 ;    /* terminated */
  48.          threadswitch() ;
  49.          printf("Multi-threading error - terminating ) ;
  50.          exit(1) ;
  51.        }
  52.       else
  53.        {
  54. /* Global pointer to thread env */
  55.          threaddata[threadindx].env = envthread ;
  56. /* Thread state to waiting to run */
  57.          threaddata[threadindx].state = 0 ;
  58. /* Modify env value for stack with a little margin for luck */
  59.          envthread[SPINDX] = (int) &stackspace[TSTACKSIZE-5] ;
  60.          threadrun(++threadindx) ;  /* Recusive call for next thread env */
  61.        }
  62.     }
  63.   else                            /* Run threads in round robin */
  64.     {
  65. /* Start the ball rolling with thread 1*/
  66.         threadindx = 0 ;
  67.         longjmp(threaddata[threadindx].env, -1) ;
  68.     }
  69. }
  70. /* Thread switcher : Will switch to next available function thread in list.
  71.    If function threads have all terminated will terminate the threads
  72.    environment and return to the root enviroment */
  73. threadswitch()
  74. { int i ;
  75.   if (threadnum != -1)
  76.   {
  77.     if (threaddata[threadindx].state != -1)
  78.       threaddata[threadindx].state = 0 ;
  79.     if (!setjmp(threaddata[threadindx].env))
  80.     {
  81.       for (i=1; i <= threadnum; i++)
  82.         { if (++threadindx >= threadnum)
  83.              threadindx = 0 ;
  84.           if (!threaddata[threadindx].state)
  85.             { threaddata[threadindx].state = 1 ;
  86.               longjmp(threaddata[threadindx].env, -1) ;
  87.             }
  88.          }
  89.        threadnum = -1 ;
  90.        longjmp(envroot, -1) ;
  91.      }
  92.   }
  93. }
  94.  
  95.  
  96.